﻿Imports System.IO.Ports
Imports System.IO

Public Class TemperatureForm

    Const SAMPLE_INTERVAL As Integer = 2

    Dim graph As MaGraph
    Dim saver As StreamWriter
    Dim sensor As SRND_DAM
    Dim sample_cnt As UInteger

    Dim chs(3) As SRNDChannel

    Dim savePath As String

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub

    Public Sub setPath(s As String)
        savePath = s
    End Sub

    Private Sub RefreshCurve()
        graph.ClearCurve()
        graph.AddCurve("温度1", SRNDChannel.axisX_buf, chs(0).axisY_buf, Color.Black)
        graph.AddCurve("温度2", SRNDChannel.axisX_buf, chs(1).axisY_buf, Color.Red)
        graph.AddCurve("温度3", SRNDChannel.axisX_buf, chs(2).axisY_buf, Color.Blue)
        graph.AddCurve("温度4", SRNDChannel.axisX_buf, chs(3).axisY_buf, Color.Pink)
        graph.RefreshCurve()
    End Sub

    Private Sub TemperatureForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        For i As Integer = 0 To 3
            chs(i) = New SRNDChannel(i)
        Next
        sample_cnt = 0
        graph = New MaGraph(zdTemperature)
        graph.SetTitle("环境温度")
        graph.SetY("温度(度)", 0, 100)
        graph.RefreshCurve()
        Dim port_name As String() = SerialPort.GetPortNames()
        If port_name IsNot Nothing Then
            For Each _name As String In port_name
                Me.cbSerial.Items.Add(_name)
                Me.cbSerial.SelectedItem = Me.cbSerial.Items(0)
            Next
        End If
    End Sub

    Private Sub btnStartSample_Click(sender As Object, e As EventArgs) Handles btnStartSample.Click
        If sensor Is Nothing Then
            Try
                sensor = New SRND_DAM(cbSerial.SelectedItem.ToString)
                sensor.InitDevice()
                lbStatus.BackColor = Color.ForestGreen
                lbStatus.Text = "Connected"
                Timer1.Start()
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        Else
            Timer1.Start()
        End If
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        sample_cnt += 1
        sensor.RequestTemp()
        If sample_cnt Mod SAMPLE_INTERVAL = 0 Then

            SRNDChannel.UpdateAxisX(sample_cnt)
            For i As Integer = 0 To 3
                chs(i).FetchData(sensor)
            Next

            '保存温度到文件
            saver = New StreamWriter(savePath + "t.csv", append:=True)
            saver.WriteLine(SRNDChannel.GetLatestX() + "," + chs(0).GetLatestY() + "," + chs(1).GetLatestY() + "," + chs(2).GetLatestY() + "," + chs(3).GetLatestY())
            saver.Close()

        End If

        RefreshCurve()
    End Sub

    Private Sub btnStopSample_Click(sender As Object, e As EventArgs) Handles btnStopSample.Click
        Timer1.Stop()
        saver.Close()
    End Sub

    Private Sub TemperatureForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        saver.Close()
    End Sub
End Class

Public Class SRNDChannel
    Const MAX_BUFFER As Integer = 599
    Public Shared axisX_buf(0) As Double
    Public Shared axisX_queue As New Queue
    Public axisY_queue As New Queue
    Public axisY_buf(0) As Double
    Private index As Integer
    Private Shared ax As Array
    Private ay As Array

    Public Sub New(i As Integer)
        Me.index = i
    End Sub

    Public Shared Sub UpdateAxisX(cnt As Integer)
        If axisX_queue.Count = MAX_BUFFER + 1 Then
            axisX_queue.Dequeue()
        Else
            ReDim Preserve axisX_buf(axisX_queue.Count)
        End If

        axisX_queue.Enqueue(cnt)

        ax = axisX_queue.ToArray()
        For i As Integer = 0 To axisX_queue.Count - 1
            axisX_buf(i) = ax(i)
        Next
    End Sub

    Public Shared Function GetLatestX() As String
        Return ax(UBound(ax)).ToString()
    End Function

    Public Sub FetchData(sensor As SRND_DAM)
        '缓存已满，清除队列头部数据
        If axisY_queue.Count = MAX_BUFFER + 1 Then
            axisY_queue.Dequeue()
        Else
            ReDim Preserve axisY_buf(axisY_queue.Count)
        End If

        axisY_queue.Enqueue(sensor.ChannelTemp(index))

        ay = axisY_queue.ToArray()
        For i As Integer = 0 To axisY_queue.Count - 1
            axisY_buf(i) = ay(i)
        Next
    End Sub

    Public Function GetLatestY() As String
        Return ay(UBound(ay)).ToString()
    End Function

End Class
